package com.anpy.bill.service.impl;

import com.anpy.bill.entity.*;
import com.anpy.bill.mapper.BillMapper;
import com.anpy.bill.mapper.MerchantMapper;
import com.anpy.bill.model.enums.DayOfWeekEnum;
import com.anpy.bill.model.param.BillListParams;
import com.anpy.bill.model.result.BillStatisticsResult;
import com.anpy.bill.model.result.MonthMoneyResult;
import com.anpy.bill.service.BillService;
import com.anpy.common.service.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("billServiceImpl")
public class BillServiceImpl extends BaseServiceImpl<BillMapper, BillEntity> implements BillService {

    @Resource
    private MerchantMapper merchantMapper;

    @Resource
    BillMapper billMapper;

    @Override
    public BillListEntity billList(Long userId, BillListParams params) {
        BillListEntity billListEntity = new BillListEntity();

        List<BillEntity> billEntities = billMapper.billList(params);
        Map<String, List<BillEntity>> collect = billEntities.stream().collect(Collectors.groupingBy(BillEntity::getCreateTime));
        List<BillListEntity.BillData> list = new ArrayList<>();
        double allExpendSum = 0;
        double allIncomeSum = 0;
        for (Map.Entry<String, List<BillEntity>> item : collect.entrySet()) {
            BillListEntity.BillData billData = new BillListEntity.BillData();
            BillListEntity.ItemData itemData = new BillListEntity.ItemData();

            String key = item.getKey();
            String[] s = key.split(" ");
            String[] split = s[0].split("-");
            LocalDate date = LocalDate.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
            // 获得日期对应的DayOfWeek
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            DayOfWeekEnum dayOfWeekEnum = DayOfWeekEnum.valueOf(dayOfWeek.name());
            List<BillEntity> value = item.getValue();
            double expendSum = value.stream().filter(bill -> bill.getType() == 0).mapToDouble(BillEntity::getMoney).sum();
            double incomeSum = value.stream().filter(bill -> bill.getType() == 1).mapToDouble(BillEntity::getMoney).sum();
            allExpendSum += expendSum;
            allIncomeSum += incomeSum;

            itemData.setDate(key + " " + dayOfWeekEnum.getChineseName());
            itemData.setExpendSum(expendSum);
            itemData.setIncomeSum(incomeSum);
            billData.setItemData(itemData);
            billData.setItemList(value);
            list.add(billData);
        }
        list.sort((o1, o2) -> o2.getItemData().getDate().compareTo(o1.getItemData().getDate()));
        billListEntity.setBillData(list);
        billListEntity.setAllIncomeSum(allIncomeSum);
        billListEntity.setAllExpendSum(allExpendSum);
        return billListEntity;
    }

    @Override
    public Boolean saveBill(BillEntity vo) {
        return save(vo);
    }

    @Override
    public Boolean deleteBill(BillDeleteParam billDeleteParam) {
        return this.removeById(billDeleteParam.getBillId());
    }

    @Override
    public Boolean updateBill(BillEntity entity) {
        return updateById(entity);
    }

    @Override
    public List<BillReportResult> report(BillReportParam billReportParam) {
        return billMapper.report(billReportParam);
    }

    @Override
    public List<MonthMoneyResult> billMonthList(Long userId, String year) {
        return billMapper.billMonthList(userId,year);
    }

    @Override
    public MonthMoneyResult billYearMoney(Long userId, String year) {
        return billMapper.billYearMoney(userId,year);
    }

    @Override
    public BillStatisticsResult statistics(Long userId) {
        return billMapper.billStatistics(userId);
    }

    @Override
    public List<MerchantEntity> merchantList(Long userId) {
        LambdaQueryWrapper<MerchantEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MerchantEntity::getUserId, userId);
        return merchantMapper.selectList(wrapper);
    }
}
